package org.nmgyjt.springboot.utils;

import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.Charsets;
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.ParseException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.*;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.params.ConnManagerParams;
import org.apache.http.conn.params.ConnPerRouteBean;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;

import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.Charset;
import java.util.*;
import java.util.Map.Entry;

@Slf4j
public class HttpUtils {

    private static HttpParams httpParams = new BasicHttpParams();
    private static ClientConnectionManager connectionManager;
    public static final int MAX_TOTAL_CONNECTIONS = 1600;
    public static final int WAIT_TIMEOUT = 60000;
    public static final int MAX_ROUTE_CONNECTIONS = 800;
    public static final int CONNECT_TIMEOUT = 120000;
    public static final int READ_TIMEOUT = 120000;

    public HttpUtils() {
    }

    public static String getRemoteAddr(HttpServletRequest request) {
        String remoteAddr = request.getHeader("X-Real-IP");
        if (StringUtils.isNotBlank(remoteAddr)) {
            remoteAddr = request.getHeader("X-Forwarded-For");
        } else if (StringUtils.isNotBlank(remoteAddr)) {
            remoteAddr = request.getHeader("Proxy-Client-IP");
        } else if (StringUtils.isNotBlank(remoteAddr)) {
            remoteAddr = request.getHeader("WL-Proxy-Client-IP");
        }

        return remoteAddr != null ? remoteAddr : request.getRemoteAddr();
    }

    public static String httpGet(String url) {
        String resault = null;

        try {
            HttpClient httpClient = getHttpClient();
            HttpGet httpget = new HttpGet(url);
            HttpResponse httpresponse = httpClient.execute(httpget);
            Integer status = httpresponse.getStatusLine().getStatusCode();
            HttpEntity entity = httpresponse.getEntity();
            switch (status) {
                case 200:
                    resault = EntityUtils.toString(entity, "utf-8");
                    break;
                default:
                    log.error(url + " " + status);
            }

            if (entity != null) {
                entity.consumeContent();
            }
        } catch (ParseException var7) {
            var7.printStackTrace();
        } catch (UnsupportedEncodingException var8) {
            var8.printStackTrace();
        } catch (IOException var9) {
            var9.printStackTrace();
        }

        return resault;
    }

    public static String httpGet(String url, Map<String, String> params) {
        return httpGet(url, params, Charsets.UTF_8);
    }

    public static String httpGet(String url, Map<String, String> params, Charset charset) {
        String resault = null;

        try {
            HttpClient httpClient = getHttpClient();
            Set<Entry<String, String>> entrySet = params.entrySet();
            Iterator<Entry<String, String>> iterator = entrySet.iterator();

            String paramsStr;
            Entry next;
            for (paramsStr = ""; iterator.hasNext(); paramsStr = paramsStr + (String) next.getKey() + "=" + (String) next.getValue() + "&") {
                next = (Entry) iterator.next();
            }

            if (!"".equals(paramsStr)) {
                paramsStr = paramsStr.substring(0, paramsStr.length() - 1);
            }

            String comleteUrl = url + "?" + paramsStr;
            HttpGet httpget = new HttpGet(comleteUrl);
            HttpResponse httpresponse = httpClient.execute(httpget);
            Integer status = httpresponse.getStatusLine().getStatusCode();
            HttpEntity entity = httpresponse.getEntity();
            switch (status) {
                case 200:
                    resault = EntityUtils.toString(entity, charset.name());
                    break;
                default:
                    log.error(url + " " + status);
            }

            if (entity != null) {
                entity.consumeContent();
            }
        } catch (ParseException var13) {
            var13.printStackTrace();
        } catch (UnsupportedEncodingException var14) {
            var14.printStackTrace();
        } catch (IOException var15) {
            var15.printStackTrace();
        }

        return resault;
    }

    public static String sendPost(String url, Map<String, String> param) {
        Set<Entry<String, String>> entrySet = param.entrySet();
        Iterator<Entry<String, String>> iterator = entrySet.iterator();

        String paramsStr;
        Entry next;
        for (paramsStr = ""; iterator.hasNext(); paramsStr = paramsStr + (String) next.getKey() + "=" + (String) next.getValue() + "&") {
            next = (Entry) iterator.next();
        }

        if (!"".equals(paramsStr)) {
            paramsStr = paramsStr.substring(0, paramsStr.length() - 1);
        }

        return sendPost(url, paramsStr);
    }

    public static String sendPost(String url, String param) {
        PrintWriter out = null;
        BufferedReader in = null;
        String result = "";

        try {
            URL realUrl = new URL(url);
            URLConnection conn = realUrl.openConnection();
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.setConnectTimeout(30000);
            conn.setReadTimeout(30000);
            out = new PrintWriter(conn.getOutputStream());
            out.print(param);
            out.flush();

            String line;
            for (in = new BufferedReader(new InputStreamReader(conn.getInputStream())); (line = in.readLine()) != null; result = result + line) {
            }
        } catch (Exception var16) {
            var16.printStackTrace();
        } finally {
            try {
                if (out != null) {
                    out.close();
                }

                if (in != null) {
                    in.close();
                }
            } catch (IOException var15) {
                var15.printStackTrace();
            }

        }

        return result;
    }

    public static <T> T sentPost(String url, Map<String, String> map, Class<T> clazz) {
        String response = sendPost(url, map);

        try {
            return FastJsonUtils.toBean(response, clazz);
        } catch (Exception var5) {
            return null;
        }
    }

    public static String clientPost(String url, Map<String, String> map, String token) {
        String resault = null;

        try {
            HttpClient httpClient = getHttpClient();
            httpClient.getParams().setParameter("http.protocol.content-charset", "UTF-8");
            httpClient.getParams().setParameter("Content-Encoding", "UTF-8");
            httpClient.getParams().setParameter("; charset=", "UTF-8");
            httpClient.getParams().setParameter("US-ASCII", "UTF-8");
            HttpPost httppost = new HttpPost(url);
            httppost.getParams().setParameter("http.protocol.content-charset", "UTF-8");
            httppost.getParams().setParameter("Content-Encoding", "UTF-8");
            httppost.getParams().setParameter("; charset=", "UTF-8");
            httppost.getParams().setParameter("US-ASCII", "UTF-8");
            Set<Entry<String, String>> entrySet = map.entrySet();
            Iterator<Entry<String, String>> iterator = entrySet.iterator();
            ArrayList params = new ArrayList();

            while (iterator.hasNext()) {
                Entry<String, String> next = (Entry) iterator.next();
                params.add(new BasicNameValuePair((String) next.getKey(), (String) next.getValue()));
            }

            httppost.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
            httppost.setHeader("Content-Type", "Application/json;charset=UTF-8");
            if (StringUtils.isNotEmpty(token))
                httppost.setHeader("Authorization", token);
            HttpResponse httpresponse = httpClient.execute(httppost);
            Integer status = httpresponse.getStatusLine().getStatusCode();
            HttpEntity entity = httpresponse.getEntity();
            switch (status) {
                case 200:
                    resault = EntityUtils.toString(entity, "utf-8");
                    break;
                default:
                    log.error(url + " " + status);
            }

            if (entity != null) {
                entity.consumeContent();
            }
        } catch (ParseException var11) {
            var11.printStackTrace();
        } catch (UnsupportedEncodingException var12) {
            var12.printStackTrace();
        } catch (IOException var13) {
            var13.printStackTrace();
        }

        return resault;
    }

    public static HttpClient getHttpClient() {
        return new DefaultHttpClient(connectionManager, httpParams);
    }

    public static String httpGet(String url, Map<String, String> params, Map<String, String> headers) {
        String resault = null;

        try {
            HttpClient e = getHttpClient();
            Set entrySet = params.entrySet();
            Iterator iterator = entrySet.iterator();

            String paramsStr;
            Entry comleteUrl;
            for (paramsStr = ""; iterator.hasNext(); paramsStr = paramsStr + (String) comleteUrl.getKey() + "=" + (String) comleteUrl.getValue() + "&") {
                comleteUrl = (Entry) iterator.next();
            }

            if (!"".equals(paramsStr)) {
                paramsStr = paramsStr.substring(0, paramsStr.length() - 1);
            }

            String comleteUrl1 = url + "?" + paramsStr;
            HttpGet httpget = new HttpGet(comleteUrl1);
            Iterator headerIterator = headers.entrySet().iterator();

            while (headerIterator.hasNext()) {
                Entry val = (Entry) headerIterator.next();
                httpget.addHeader((String) val.getKey(), (String) val.getValue());
            }

            HttpResponse httpresponse = e.execute(httpget);
            Integer status = httpresponse.getStatusLine().getStatusCode();
            HttpEntity entity = httpresponse.getEntity();
            switch (status) {
                case 200:
                    resault = EntityUtils.toString(entity, "utf-8");
                    break;
                case 555:
                    resault = EntityUtils.toString(entity, "utf-8");
                    break;
                default:
                    log.error(url + " " + status);
            }

            if (entity != null) {
                entity.consumeContent();
            }
        } catch (ParseException var15) {
            var15.printStackTrace();
        } catch (UnsupportedEncodingException var16) {
            var16.printStackTrace();
        } catch (IOException var17) {
            var17.printStackTrace();
        }

        return resault;
    }

    public static String httpDelete(String url, Map params, Map headers) {
        String resault = null;

        try {
            HttpClient e = getHttpClient();
            Set entrySet = params.entrySet();
            Iterator iterator = entrySet.iterator();

            String paramsStr;
            Entry comleteUrl;
            for (paramsStr = ""; iterator.hasNext(); paramsStr = paramsStr + (String) comleteUrl.getKey() + "=" + (String) comleteUrl.getValue() + "&") {
                comleteUrl = (Entry) iterator.next();
            }

            if (!"".equals(paramsStr)) {
                paramsStr = paramsStr.substring(0, paramsStr.length() - 1);
            }

            String comleteUrl1 = url + "?" + paramsStr;
            HttpDelete httpDelete = new HttpDelete(comleteUrl1);
            Iterator headerIterator = headers.entrySet().iterator();

            while (headerIterator.hasNext()) {
                Entry val = (Entry) headerIterator.next();
                httpDelete.addHeader((String) val.getKey(), (String) val.getValue());
            }

            HttpResponse httpresponse = e.execute(httpDelete);
            Integer status = httpresponse.getStatusLine().getStatusCode();
            HttpEntity entity = httpresponse.getEntity();
            switch (status) {
                case 200:
                    resault = EntityUtils.toString(entity, "utf-8");
                    break;
                case 555:
                    resault = EntityUtils.toString(entity, "utf-8");
                    break;
                default:
                    log.error(url + " " + status);
            }

            if (entity != null) {
                entity.consumeContent();
            }
        } catch (ParseException var15) {
            var15.printStackTrace();
        } catch (UnsupportedEncodingException var16) {
            var16.printStackTrace();
        } catch (IOException var17) {
            var17.printStackTrace();
        }

        return resault;
    }

    public static String sendHttpPost(String url, JSONObject json, HashMap<String, String> headers) {
        String jsonStr = json.toString();
        HttpPost post = new HttpPost(url);
        String response = "";
        RequestConfig config = RequestConfig.custom().setConnectionRequestTimeout(20000)
                .setConnectTimeout(20000).setSocketTimeout(20000).build();
        CloseableHttpClient client = null;
        try {
            client = HttpClients.custom().setDefaultRequestConfig(config)
                    .setSslcontext(SSLContexts.custom().loadTrustMaterial(null, (x509Certificates, s) -> true).build())
                    .setMaxConnTotal(2000)
                    .setMaxConnPerRoute(5000).build();
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                post.addHeader(entry.getKey(), entry.getValue());
            }
            StringEntity requestBody = new StringEntity(jsonStr, "utf-8");

            log.info("requestData >>" + jsonStr);
            //logger.info("requestBody >>" + JSONObject.toJSONString(requestBody));
            post.setEntity(requestBody);
            log.info("请求参数{}", JSONObject.toJSONString(post.getEntity().getContent()));
            CloseableHttpResponse httpResponse = client.execute(post);
            InputStream inStream = httpResponse.getEntity().getContent();
            BufferedReader reader = new BufferedReader(new InputStreamReader(inStream, "utf-8"));
            StringBuilder strber = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                strber.append(line + "\n");
            }
            inStream.close();
            response = strber.toString();
        } catch (Exception e) {
            log.info(e.getMessage());
        } finally {
            try {
                client.close();
            } catch (Exception e) {
                log.info(e.getMessage());
            }
        }
        return response;
    }


    public static String sendHttpPatch(String url, JSONObject json, HashMap<String, String> headers) {
        String jsonStr = json.toString();
        HttpPatch post = new HttpPatch(url);
        String response = "";
        RequestConfig config = RequestConfig.custom().setConnectionRequestTimeout(10000)
                .setConnectTimeout(10000).setSocketTimeout(20000).build();
        CloseableHttpClient client = null;
        try {
            client = HttpClients.custom().setDefaultRequestConfig(config)
                    .setSslcontext(SSLContexts.custom().loadTrustMaterial(null, (x509Certificates, s) -> true).build())
                    .setMaxConnTotal(500)
                    .setMaxConnPerRoute(200).build();
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                post.addHeader(entry.getKey(), entry.getValue());
            }
            StringEntity requestBody = new StringEntity(jsonStr, "utf-8");

            post.setEntity(requestBody);
            CloseableHttpResponse httpResponse = client.execute(post);
            InputStream inStream = httpResponse.getEntity().getContent();
            BufferedReader reader = new BufferedReader(new InputStreamReader(inStream, "utf-8"));
            StringBuilder strber = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                strber.append(line + "\n");
            }
            inStream.close();
            response = strber.toString();
        } catch (Exception e) {
            log.info(e.getMessage());
        } finally {
            try {
                client.close();
            } catch (Exception e) {
                log.info(e.getMessage());
            }
        }
        return response;
    }

    public static String sendHttpPut(String url, JSONObject json, HashMap<String, String> headers) {
        String jsonStr = json.toString();
        HttpPut post = new HttpPut(url);
        String response = "";
        RequestConfig config = RequestConfig.custom().setConnectionRequestTimeout(10000)
                .setConnectTimeout(10000).setSocketTimeout(20000).build();
        CloseableHttpClient client = null;
        try {
            client = HttpClients.custom().setDefaultRequestConfig(config)
                    .setSslcontext(SSLContexts.custom().loadTrustMaterial(null, (x509Certificates, s) -> true).build())
                    .setMaxConnTotal(500)
                    .setMaxConnPerRoute(200).build();
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                post.addHeader(entry.getKey(), entry.getValue());
            }
            StringEntity requestBody = new StringEntity(jsonStr, "utf-8");

            // logger.info("requestData >>" + jsonStr);
            // logger.info("requestBody >>" + JSONObject.toJSONString(requestBody));
            post.setEntity(requestBody);
            CloseableHttpResponse httpResponse = client.execute(post);
            InputStream inStream = httpResponse.getEntity().getContent();
            BufferedReader reader = new BufferedReader(new InputStreamReader(inStream, "utf-8"));
            StringBuilder strber = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                strber.append(line + "\n");
            }
            inStream.close();
            response = strber.toString();
        } catch (Exception e) {
            log.info(e.getMessage());
        } finally {
            try {
                client.close();
            } catch (Exception e) {
                log.info(e.getMessage());
            }
        }
        return response;
    }

    static {
        ConnManagerParams.setMaxTotalConnections(httpParams, 800);
        ConnManagerParams.setTimeout(httpParams, 60000L);
        ConnPerRouteBean connPerRoute = new ConnPerRouteBean(400);
        ConnManagerParams.setMaxConnectionsPerRoute(httpParams, connPerRoute);
        HttpConnectionParams.setConnectionTimeout(httpParams, 10000);
        HttpConnectionParams.setSoTimeout(httpParams, 10000);
        SchemeRegistry registry = new SchemeRegistry();
        registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
        registry.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443));
        connectionManager = new ThreadSafeClientConnManager(httpParams, registry);
    }
}
